﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Web.UI.HtmlControls;
using System.Collections;
using System.Net.Mail;
using System.Data;

public partial class Dashboard : System.Web.UI.Page
{
    public static string loggedInUserName = "";
    public static string loggedInUserType = "";

    public static int UserTypeId { get; set; }
    public static int level { get; set; }
    public static string LoginName { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["LoginName"] == null || Session["UserId"] == null)
        {
            Response.Redirect("Home.aspx");
        }
        else
        {
            loggedInUserType = Session["UserType"].ToString();
            loggedInUserName = Session["LoginName"].ToString();
            FillDropdowns();

            UserTypeId = Convert.ToInt32(Session["UserTypeId"]);
            level = Convert.ToInt32(Session["level"]);
            LoginName = Convert.ToString(Session["LoginName"]);
            
        }
    }
    
    private void FillDropdowns()
    {
        ArrayList groups = new ArrayList();
        if(Session["UserTypeId"] !=null)
            groups = EventDAO.getGroups(Convert.ToInt32(Session["UserTypeId"]), Convert.ToInt32(Session["level"]));
        addGroups.DataSource = groups;
        eventGroups.DataSource = groups;
        addGroups.DataBind();
        eventGroups.DataBind();

        ArrayList customers = new ArrayList();
        customers = EventDAO.getCustomerNames();
        addCompanies.DataSource = customers;
        eventCompanies.DataSource = customers;
        addCompanies.DataBind();
        eventCompanies.DataBind();

        // Actually this array list should be populated from the server(database).
        //ArrayList alEmails = new ArrayList();
        //alEmails.Add("shdbeflld@frmdb.com");
        //addMails.DataSource = alEmails;
        //addMails.DataBind();
    }

    //this method only updates title and a description
    //this is called when a event is clicked on the calendar
    [System.Web.Services.WebMethod(true)]
    public static ImproperCalendarEvent UpdateEvent(CalendarEvent cevent)
    {
        cevent.start = cevent.start.ToLocalTime();
        cevent.end = cevent.end.ToLocalTime();
        // In case of no users being selected, get all tthe users who belong to the selected group.
        if (cevent.users == null)
        {
            ArrayList users = EventDAO.getUsersForAGroup(cevent.groupname);
            string[] strings = Array.ConvertAll<object, string>(users.ToArray(), Convert.ToString);
            cevent.users = strings;
        }

        ArrayList allUsersList = new ArrayList();
        ArrayList usersOnLeaveList = new ArrayList();
        ArrayList remainingUsersList = new ArrayList();

        allUsersList.AddRange(cevent.users);

        for (int i = 0; i < allUsersList.Count; i++)
        {
            int isLeave = EventDAO.checkIfAnyUserIsOnLeave(allUsersList[i].ToString(), cevent.start, cevent.end);

            if (isLeave != 0)
            {
                usersOnLeaveList.Add(allUsersList[i].ToString());
            }
            else
            {
                remainingUsersList.Add(allUsersList[i].ToString());
            }
        }

        cevent.users = Array.ConvertAll<object, string>(remainingUsersList.ToArray(), Convert.ToString);
        ImproperCalendarEvent impEvent = new ImproperCalendarEvent();
        impEvent.id = cevent.id;
        impEvent.title = cevent.title;
        impEvent.description = cevent.description;
        impEvent.companyname = cevent.companyname;
        impEvent.groupname = cevent.groupname;
        impEvent.users = cevent.users;
        impEvent.mails = cevent.mails;
        impEvent.start = cevent.start.ToString("dd-MM-yyyy hh:mm:ss tt");
        impEvent.end = cevent.end.ToString("dd-MM-yyyy hh:mm:ss tt");

        return impEvent;//return the users to be added.
}

    [System.Web.Services.WebMethod]
    public static string updateEventCompleted(ImproperCalendarEvent improperEvent)
    {
        CalendarEvent cevent = new CalendarEvent()
        {
            id = improperEvent.id,
            title = improperEvent.title,
            description = improperEvent.description,
            companyname = improperEvent.companyname,
            groupname = improperEvent.groupname,
            users = improperEvent.users,
            mails = improperEvent.mails,
            start = DateTime.ParseExact(improperEvent.start, "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture),
            end = DateTime.ParseExact(improperEvent.end, "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture)
        };

        List<int> idList = (List<int>)System.Web.HttpContext.Current.Session["idList"];
        if (idList != null && idList.Contains(cevent.id))
        {
            if (CheckAlphaNumeric(cevent.title) && cevent.users !=null )
            {
                //DateTime start = DateTime.ParseExact(cevent.start.ToString(), "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture);
                //DateTime end = DateTime.ParseExact(cevent.end.ToString(), "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture);

                DateTime start = cevent.start;
                DateTime end = cevent.end;
        
                EventDAO.updateEvent(cevent.id, cevent.title, cevent.description, cevent.companyname, cevent.groupname, cevent.users,start,end);

                return "updated event with id:" + cevent.id + " update title to: " + cevent.title +
                " update description to: " + cevent.description;
            }

        }

        return "unable to update event with id:" + cevent.id + " title : " + cevent.title +
            " description : " + cevent.description;
    }

    //this method only updates start and end time
    //this is called when a event is dragged or resized in the calendar
    [System.Web.Services.WebMethod(true)]
    public static string UpdateEventTime(ImproperCalendarEvent improperEvent)
    {
        List<int> idList = (List<int>)System.Web.HttpContext.Current.Session["idList"];
        if (idList != null && idList.Contains(improperEvent.id))
        {
            EventDAO.updateEventTime(improperEvent.id,
                DateTime.ParseExact(improperEvent.start, "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture),
                DateTime.ParseExact(improperEvent.end, "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture));

            return "updated event with id:" + improperEvent.id + "update start to: " + improperEvent.start +
                " update end to: " + improperEvent.end;
        }

        return "unable to update event with id: " + improperEvent.id;
    }

    //called when delete button is pressed
    [System.Web.Services.WebMethod(true)]
    public static String deleteEvent(int id)
    {
        //idList is stored in Session by JsonResponse.ashx for security reasons
        //whenever any event is update or deleted, the event id is checked
        //whether it is present in the idList, if it is not present in the idList
        //then it may be a malicious user trying to delete someone elses events
        //thus this checking prevents misuse
        List<int> idList = (List<int>)System.Web.HttpContext.Current.Session["idList"];
        if (idList != null && idList.Contains(id))
        {
            EventDAO.deleteEvent(id);
            return "deleted event with id:" + id;
        }

        return "unable to delete event with id: " + id;

    }

    //called when Add button is clicked
    //this is called when a mouse is clicked on open space of any day or dragged 
    //over mutliple days
    [System.Web.Services.WebMethod]
    public static ImproperCalendarEvent addEvent(ImproperCalendarEvent improperEvent)
    {
        CalendarEvent cevent = new CalendarEvent()
        {
            title = improperEvent.title,
            description = improperEvent.description,
            companyname = improperEvent.companyname,
            groupname = improperEvent.groupname,
            users = improperEvent.users,
            mails = improperEvent.mails,
            start = DateTime.ParseExact(improperEvent.start, "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture),
            end = DateTime.ParseExact(improperEvent.end, "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture)
        };

        // In case of no users being selected, get all tthe users who belong to the selected group.
        if (cevent.users == null)
        {
            ArrayList users = EventDAO.getUsersForAGroup(cevent.groupname);
            string[] strings = Array.ConvertAll<object, string>(users.ToArray(), Convert.ToString);
            cevent.users = strings;
        }

        ArrayList allUsersList = new ArrayList();
        ArrayList usersOnLeaveList = new ArrayList();
        ArrayList remainingUsersList = new ArrayList();

        allUsersList.AddRange(cevent.users);

        for (int i = 0; i < allUsersList.Count; i++)
        {
            int isLeave = EventDAO.checkIfAnyUserIsOnLeave(allUsersList[i].ToString(), cevent.start, cevent.end);

            if (isLeave != 0)
            {
                usersOnLeaveList.Add(allUsersList[i].ToString());
            }
            else
            {
                remainingUsersList.Add(allUsersList[i].ToString());
            }
        }

        cevent.users = Array.ConvertAll<object, string>(remainingUsersList.ToArray(), Convert.ToString);

        ImproperCalendarEvent impEvent = new ImproperCalendarEvent();
        impEvent.title = cevent.title;
        improperEvent.description = cevent.description;
        improperEvent.companyname = cevent.companyname;
        improperEvent.groupname = cevent.groupname;
        improperEvent.users = cevent.users;
        improperEvent.mails = cevent.mails;
        improperEvent.start = cevent.start.ToString("dd-MM-yyyy hh:mm:ss tt");
        improperEvent.end = cevent.end.ToString("dd-MM-yyyy hh:mm:ss tt");

        return improperEvent;//return the users to be added.
    }

    [System.Web.Services.WebMethod]
    public static int addEventCompleted(ImproperCalendarEvent improperEvent)
    {
        CalendarEvent cevent = new CalendarEvent()
        {
            title = improperEvent.title,
            description = improperEvent.description,
            companyname = improperEvent.companyname,
            groupname = improperEvent.groupname,
            users = improperEvent.users,
            mails=improperEvent.mails,
            start = DateTime.ParseExact(improperEvent.start, "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture),
            end = DateTime.ParseExact(improperEvent.end, "dd-MM-yyyy hh:mm:ss tt", CultureInfo.InvariantCulture)
        };
        ArrayList mailsList = new ArrayList();

        if (CheckAlphaNumeric(improperEvent.title))
        {
            int key = EventDAO.addEvent(cevent);
            List<int> idList = (List<int>)System.Web.HttpContext.Current.Session["idList"];

            if (idList != null)
            {
                ArrayList al = new ArrayList();
                if (cevent.mails != null)
                {
                    for (int k = 0; k < cevent.mails.Length; k++)
                    {
                        if (cevent.mails[k].Contains('@'))
                        {
                            mailsList.Add(cevent.mails[k]);
                        }
                        else
                        {
                            al.Add(cevent.mails[k]);
                        }
                    }
                }

                for (int i = 0; i < cevent.users.Length; i++)
                {
                    User u = EventDAO.getUserByName(cevent.users[i]);
                    if (u != null && al.Contains(u.userName))
                    {
                        mailsList.Add(u.emailId);
                    }
                }

                idList.Add(key);
            }
            try
            {
                SendEmail(mailsList, cevent);
            }
            catch (Exception ex)
            {
 
            }

            return key;//return the primary key of the added cevent object
        }

        return -1;//return a negative number just to signify nothing has been added
    }

    private static void SendEmail(ArrayList mailsList, CalendarEvent cevent)
    {
        MailMessage mailMessage = new MailMessage();
        SmtpClient smtpClient = new SmtpClient("smtp.gmail.com",587);
        smtpClient.EnableSsl = true;
        smtpClient.Credentials = new System.Net.NetworkCredential("organizerwork@gmail.com", "Rizwan@123"); // User id and password.
        mailMessage.From = new MailAddress("organizerwork@gmail.com");
        for (int i = 0; i < mailsList.Count; i++)
        {
            mailMessage.To.Add(new MailAddress("organizerwork@gmail.com"));
            mailMessage.To.Add(new MailAddress(mailsList[i].ToString()));
        }
        string users = String.Join(",", cevent.users);
        mailMessage.ReplyTo = new MailAddress("organizerwork@gmail.com");
        mailMessage.Subject = "Your appointment details";
        mailMessage.Body = "Your appointment details are as follows.\n\n Title : "+ cevent.title+"\n Description : "+cevent.description+
            "\n Group Name : " + cevent.groupname + "\n Company : " + cevent.companyname + "\n Users : " + users + "\n Start time : " + cevent.start + "\n End time : " + cevent.end + " \n\nRegards \n admin.";
        smtpClient.Send(mailMessage);
    }

    [System.Web.Services.WebMethod(true)]
    public static string PopulateAddUsers(string selGroupName)
    {
        ArrayList users = EventDAO.getUsersForAGroup(selGroupName);
        string[] strings = Array.ConvertAll<object, string>(users.ToArray(), Convert.ToString);
        string ret = "";

        if (loggedInUserType != null && loggedInUserType.Equals(selGroupName))
        {
            ret = loggedInUserName;
        }
        else
        {
            for (int i = 0; i < strings.Length; i++)
            {
                ret = ret + strings[i].ToString() + ",";
            }
        }
        return ret.Trim(',');
    }

    [System.Web.Services.WebMethod(true)]
    public static string PopulateUpdateUsers(string selGroupName)
    {
        ArrayList users = EventDAO.getUsersForAGroup(selGroupName);
        string[] strings = Array.ConvertAll<object, string>(users.ToArray(), Convert.ToString);
        string ret = "";
        
        for (int i = 0; i < strings.Length; i++)
        {
            ret = ret + strings[i].ToString() + ",";
        }
        return ret.Trim(',');
    }

    [System.Web.Services.WebMethod(true)]
    public static string PopulateAddCustomerRelatedFields(string custName)
    {
        DataTable dt = EventDAO.getCustomerRelatedFields(custName);

        string address = dt.Rows[0].ItemArray[1].ToString();
        string email = dt.Rows[0].ItemArray[2].ToString();
        string person = dt.Rows[0].ItemArray[3].ToString();
        string number = dt.Rows[0].ItemArray[4].ToString();
        string ret = custName + "#$#" + address + "#$#" + email + "#$#" + person + "#$#" + number;

        return ret.Trim(',');
    }

    private static bool CheckAlphaNumeric(string str)
    {
        return Regex.IsMatch(str, @"^[a-zA-Z0-9 ]*$");
    }

    [System.Web.Services.WebMethod(true)]
    public static string GetDaysEvents(DateTime currentDate)
    {
        DateTime dt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
        DateTime start = new DateTime(1970, 1, 1);

        start = start.AddSeconds((dt - start).TotalSeconds);
        String result = String.Empty;

        result += "";

        foreach (CalendarEvent cevent in EventDAO.getDaysEvents(start, level, LoginName))
        {
            result += convertCalendarEventIntoString(cevent);
        }

        if (result.EndsWith("#"))
        {
            result = result.Substring(0, result.Length - 1);
        }

        result += "";

        return result;
    }

    private static String convertCalendarEventIntoString(CalendarEvent cevent)
    {
        String allDay = "true";
        if (ConvertToTimestamp(cevent.start).ToString().Equals(ConvertToTimestamp(cevent.end).ToString()))
        {
            if (cevent.start.Hour == 0 && cevent.start.Minute == 0 && cevent.start.Second == 0)
            {
                allDay = "true";
            }
            else
            {
                allDay = "false";
            }
        }
        else
        {
            if (cevent.start.Hour == 0 && cevent.start.Minute == 0 && cevent.start.Second == 0
                && cevent.end.Hour == 0 && cevent.end.Minute == 0 && cevent.end.Second == 0)
            {
                allDay = "true";
            }
            else
            {
                allDay = "false";
            }
        }

        string[] str = cevent.users;
        string users = "";
        for (int i = 0; i < str.Length; i++)
        {
            users = users + str[i] + ",";
        }
        users = users.TrimEnd(',');

        //HttpContext.Current.Server.HtmlEncode(cevent.groupname)
        return "{" +
                  "id: '" + cevent.id + "'^" +
                  "title: '" + HttpContext.Current.Server.HtmlEncode(cevent.title) + "'^" +
                  "start:  " + ConvertToTimestamp(cevent.start).ToString() + "^" +
                  "end: " + ConvertToTimestamp(cevent.end).ToString() + "^" +
                  "allDay:" + allDay + "^" +
                  "description: '" + HttpContext.Current.Server.HtmlEncode(cevent.description) + "'^" +
                  "companyname: '" + HttpContext.Current.Server.HtmlEncode(cevent.companyname) + "'^" +
                  "groupname: '" + HttpContext.Current.Server.HtmlEncode(cevent.groupname) + "'^" +
                  "users: '" + HttpContext.Current.Server.HtmlEncode(users) + "'" +
                  "}#";
    }

    private static long ConvertToTimestamp(DateTime value)
    {
        long epoch = (value.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
        return epoch;
    }

}
